package com.bysc.commentservice.handler;

import com.alibaba.fastjson.JSON;
import com.bysc.baseservice.config.RabbitmqConfig;
import com.bysc.baseservice.handler.BaiYunException;
import com.bysc.commentservice.client.UserClient;
import com.bysc.commentservice.entity.vo.NoticeInnerClass;
import com.bysc.commentservice.utils.CommentService;
import com.bysc.commonutils.ResultCode;
import com.bysc.commonutils.Results;
import com.bysc.commonutils.constant.MessageConstant;
import com.bysc.commonutils.constant.RedisConstant;
import com.bysc.commonutils.enums.CommentEnum;
import com.bysc.commonutils.utils.ScoreUtil;
import com.bysc.commonutils.vo.PostStatsVo;
import com.bysc.commonutils.vo.UserInfoVo;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Date;
import java.util.HashSet;
import java.util.List;

import static com.bysc.commonutils.constant.RedisConstant.*;

@Component
public class ReceiveHandler {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private CommentService commentService;
    @Autowired
    private UserClient userClient;
    /**
     * 帖子分数消费端
     * 监听帖子分数计算消息
     */
    @RabbitListener(queues = {RabbitmqConfig.QUEUE_POST_SCORE})
    public void consumePostScoreMessage(Message message, Channel channel) {
        try {
            // 1. 获取帖子的基础数据
            Query query = new Query();
            query.fields().include("gmtCreate").include("userId");
            List<NoticeInnerClass> list = mongoTemplate.find(query, NoticeInnerClass.class, "post");
            HashSet<ZSetOperations.TypedTuple> set = new HashSet<>();
            // 2. 计算每个帖子的热度分数
            for (NoticeInnerClass post : list) {
                String id = post.getId();
                Date gmtCreate = post.getGmtCreate();
                PostStatsVo postStatsVo = new PostStatsVo();

                // 获取 Redis 中存储的帖子点赞、收藏和浏览量
                String key = RedisConstant.COMMENT_POST + id;  // 帖子相关的 Redis 键
                if (!redisTemplate.hasKey(key)) {
                    continue;
                }
                int like = (int) redisTemplate.opsForHash().get(key, _LIKE);
                int collect = (int) redisTemplate.opsForHash().get(key, _COLLECT);
                int view = (int) redisTemplate.opsForHash().get(key, _VIEW);
                //获取用户信息
                UserInfoVo user = JSON.parseObject(JSON.toJSONString(userClient.getUserInfoById(post.getUserId()).getData().get("user")), UserInfoVo.class);
                if (user != null) {
                    postStatsVo.setActiveUser(user.getIsActive());
                    postStatsVo.setAssociationMember( user.getIsJoin());
                }
                // 将点赞、收藏和浏览量信息封装到 PostStatsVo
                postStatsVo.setLikes(like);
                postStatsVo.setCollects(collect);
                postStatsVo.setViews(view);
                postStatsVo.setComments(commentService.getCommentCount(id));
                // 计算帖子热度分数
                double heatScore = ScoreUtil.calculateHeatScore(postStatsVo, gmtCreate, CommentEnum.POST);
                //将id, heatScore存入set
                set.add(new DefaultTypedTuple(id, heatScore));
                System.out.println("帖子：" + id + "，热度分数：" + heatScore);
                // 将计算出的热度分数存入 Redis 的 ZSet（有序集合）
                if (set.size() % 10 == 0) {
                    redisTemplate.opsForZSet().add("post_score", set);
                    set.clear();
                }
            }
            redisTemplate.opsForZSet().add("post_score", set);
            System.out.println("帖子分数计算完成！");
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            try {
                e.printStackTrace();
                channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}
